import UIManager from "../../ui/UIManager"
import ResKeeper from "../../res/ResKeeper"
import {UIType } from "../../ui/UIType"
import EventProxy from "../../event/EventProxy";
import ResLoader from "../../res/ResLoader";
import RedTipAble from "../../interface/RedTipAble";
import RedTipManager from "../../redtip/RedTipManager";
import { RedTipEventName } from "../../redtip/RedTipConst";
import GuideManager from "../../guide/GuideManager";

/**
 * 所有view组件的父类。
 * 直接挂载到场景中的界面不在onEnable中调用model 因为 这时的onEnable走在start之前，这时model还是null的可以将设置model的操作放到onLoad中
 * 给模型或者控制器添加监听放到对应的addXXXListener方法中。保证这时候已经有了model和controller。
 * 每次都会被回收的界面由于更新内容的需要，只能在onEnable中更新逻辑。
 * 所有的itemview 都通过init方法更新内容。
 */
const { ccclass, property } = cc._decorator;

@ccclass
export default abstract class BaseView extends cc.Component implements RedTipAble{


    private uiType: UIType;


    protected model: any;

    protected controller : any;

    protected loader:ResLoader;

    //由于model可能添加很多事件，在界面销毁的时候一个一个的移除比较麻烦，所以借助EventProxy做个简化操作。
    protected eventProxy: EventProxy;

    protected redTipManager:RedTipManager;

    constructor(){
        super();
        this.eventProxy = new EventProxy();
        this.redTipManager = RedTipManager.instance();
    }

    // 获得组件自身的资源加载器。如果自己没有给View添加res/ResKeeper组件，这里就返回null。
    private selfLoader():ResLoader{
        let parent:cc.Node = this.node;
        while(parent){
            let keeper = parent.getComponent(ResKeeper);
            if(keeper){
                return keeper.loader;
            }else{
                parent = parent.getParent();
            }
        }

        return null;
    }

    //如果自身没有添加keeper组件，寻找父节点的，一般会找到scene的组件使用。
    getLoader():ResLoader{

        if(!this.loader){
            let temp = this.selfLoader();
            if(temp){
                this.loader = temp;
                return this.loader;
            }
            this.loader = UIManager.instance().getLoader();
            return this.loader;
        }
        return this.loader;
    }


    /**
     * 
     * @param model 模型
     */
    setModel(model){
        if(this.model == model){
            return ;
        }
        if(this.eventProxy){
            this.eventProxy.removeAllEventListener(); 
        }
        this.model = model;
        if(this.model){
            this.eventProxy.setDispatcher(this.model); 
            this.addModelListener();
        } 
       
       
    }

    getRedTipName(){
        return this.node.name;
    }
    getRedTipNode(){
        return this.node;
    }

    addRedTipListener(){
        if(this.redTipManager.isHaveLayer(this)){
            this.redTipManager.addEventListener(RedTipEventName.ADD_RED_TIP,this.addRedTip,this)
            this.redTipManager.addEventListener(RedTipEventName.DELETE_RED_TIP,this.removeRedTip,this)
            this.redTipManager.addWidgetRedTipByOnEnter(this);
        }
    }



    addRedTip(redTipType:number,id:number){
        this.redTipManager.addWidgetRedTipByNotify(this,redTipType,id)
    }

    removeRedTip(redTipType:number,id:number){
        this.redTipManager.deleteWidgetRedTipByNotify(this,redTipType,id)
    }

    removeRedTipListener(){
        if(this.redTipManager.isHaveLayer(this)){
            this.redTipManager.removeEventListener(RedTipEventName.ADD_RED_TIP,this.addRedTip,this)
            this.redTipManager.removeEventListener(RedTipEventName.DELETE_RED_TIP,this.removeRedTip,this)
        }
    }

    //在这里添加事件监听函数
    addModelListener(){

    }

    addControllerListener(){

    }

    start(){
        
    }

    getModel(){
        return this.model;
    }

    /**
     * 
     * @param controller 控制器
     */
    setController(controller){
        this.controller = controller;
        this.addControllerListener();
    }

    getUIType():UIType{
        return this.uiType;
    }

    setUIType(type:UIType){
        this.uiType = type;
    }

    /**
     * 弹出框的半透明背景颜色。
     */
    getBgColor() : cc.Color {
        return cc.color(0, 0, 0, 200);
    }

    /**
     * 是否隐藏底层的内容。
     */
    isHideBg(){
        return false;
    }


    show(isPool:boolean = false) {
        UIManager.instance().pushView(this,isPool);
    }

    //将界面充UI管理器中移除。
    close(){
        // cc.log("close view ");
        UIManager.instance().popView(this); 
        // this.controller.close(this);   
    }

    onLoad(){
        this.addRedTipListener();
    }
    //生命周期函数，在界面销毁时自动调用，所有子类如果重写此方法，一定要调用super.onDestroy();
    onDestroy(){
        this.eventProxy.removeAllEventListener();
        this.removeRedTipListener();
    }

    /**
     * 
     * @param name 需要查找的节点名称，最好带路径，否则会进行递归查找。
     * @param node 从哪个节点开始查找 默认从this.node开始查找。
     */
    find(name,node?:cc.Node){
        if(!node){
            node = this.node;
        }
        let temp = cc.find(name,node);
        if(temp){
            return temp;
        }else{
            let count = node.children.length;
            for (let index = 0; index <count; index++) {
                const element = node.children[index];
                temp = this.find(name,element);
                if(temp){
                    return temp;
                }
            }
            return null;
        }
    }

    setTimeout(time:number,func:Function){
        this.node.runAction(cc.sequence(cc.delayTime(time),cc.callFunc(func)));
    }


    checkGuide(funcName: string,id?:any):boolean{
        // cc.log(' GuideManager.instance().isHaveGuide() ',GuideManager.instance().isHaveGuide())
        if(GuideManager.instance().isHaveGuide()){
            return  GuideManager.instance().check(this.node.name, funcName,id)
        }else{
            return true;
        }
       
    }    
}
